package com.kobeliu.controller;


import com.google.gson.Gson;
import com.kobeliu.base.BaseInfoProperties;
import com.kobeliu.pojo.Users;
import com.kobeliu.pojo.bo.RegistryLoginBO;
import com.kobeliu.pojo.vo.SaasUserVO;
import com.kobeliu.pojo.vo.UsersVO;
import com.kobeliu.result.GraceJSONResult;
import com.kobeliu.result.ResponseStatusEnum;
import com.kobeliu.result.SMSSendResult;
import com.kobeliu.service.UsersService;
import com.kobeliu.utils.IPUtil;
import com.kobeliu.utils.JwtUtils;
import com.kobeliu.utils.SMSUtils;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@Slf4j
@RequestMapping("/saas")
//企业使用
public class SaasPassportController extends BaseInfoProperties {

    @Autowired
    private SMSUtils smsUtils;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private UsersService usersService;

    @RequestMapping(method = RequestMethod.POST,path = "getQRToken")
    public GraceJSONResult getQRToken(){

        //生成扫码登录的token
        String qrToken = UUID.randomUUID().toString();

        //时效性 存redis 若超过时效 需要刷新生成新的二维码
        redis.setnx60s(SAAS_PLATFORM_LOGIN_TOKEN+":"+ qrToken,qrToken);

        //存入redis标记当前的qrToken未被扫描读取
        redis.setnx60s(SAAS_PLATFORM_LOGIN_TOKEN_READ+":"+qrToken,"0,"+qrToken);

        //返回前端让前端携带token
        return GraceJSONResult.ok(qrToken);

    }

    @RequestMapping(method = RequestMethod.POST,path = "scanCode")
    public GraceJSONResult scanCode(String qrToken,HttpServletRequest request){

        String redisQRToken = redis.get(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + qrToken);
        if(StringUtils.isBlank(redisQRToken)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FAILED);
        }

        String appUserId = request.getHeader("appUserId");
        String appUserToken = request.getHeader("appUserToken");

        if(StringUtils.isBlank(appUserId) || StringUtils.isBlank(appUserToken)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.HR_TICKET_INVALID);
        }

        String userStr = jwtUtils.checkJwt(appUserToken.split("@")[1]);
        if(StringUtils.isBlank(userStr)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.HR_TICKET_INVALID);
        }

        if(StringUtils.isBlank(qrToken)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.FAILED);
        }

        //此时 检测通过
        //生成预登录Token
        String preToken = UUID.randomUUID().toString();
        //覆盖原token
        redis.setnx60s(SAAS_PLATFORM_LOGIN_TOKEN_READ+":"+qrToken,"1,"+preToken);

        //返回给手机端，app下次携带preToken


        return GraceJSONResult.ok(preToken);
    }

    // ====================跳过扫码功能 START============================

    /**
     * 模拟扫码前 到 确认登录前的流程
     * @param qrToken
     * @return
     */
    @RequestMapping(method = RequestMethod.POST,path = "codeHasBeenRead")
    public GraceJSONResult getQRToken1(String qrToken){

        //扫码逻辑整理
        /**
         *
         * 1.后端生成一个QRToken，存入redis中
         * 2.前端定时任务，查看QRToken
         * 3.若手机用户扫描了二维码 拿取手机端的token写入redis中
         */
        String staticStr = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJpZFwiOlwiMTAwMVwiLFwidXNlcm5hbWVcIjpcImFkbWluXCIsXCJyZW1hcmtcIjpcIueuoeeQhuWRmFwiLFwiZmFjZVwiOlwiaHR0cDovL2hpcmUudC5tdWtld2FuZy5jb20vc3RhdGljL2FkbWluRmFjZS82NDQ4NDJlMy0wMTczLTQyYzAtYTdhOS1hYmRiYTA5YzM1OGIucG5nXCJ9In0.LLWceUgWOxfzHUliZcdbPPoVyFgs3NAEc42om2_VzqI";

        redis.set(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + qrToken,"1,"+staticStr);

        List<String> list = new ArrayList<>();

        log.info("===========================================");
        log.info("qrToken为:{}",qrToken);
        log.info("===========================================");

        // 0,qrToken 1,preToken

        list.add("1");
        list.add(staticStr);

        //此时模拟已扫码的状态

        //若0，未标记 若1，已标记，等待前端点确认登陆
        //返回前端让前端携带token
        return GraceJSONResult.ok(list);

    }

    @RequestMapping(method = RequestMethod.POST,path = "goQRLogin")
    public GraceJSONResult goQRLogin1(String userId,String qrToken,String preToken){

        String preTokenRedisArr = redis.get(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + qrToken);

        if(StringUtils.isBlank(preTokenRedisArr)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_STATUS_ERROR);
        }

        String preTokenRedis = preTokenRedisArr.split(",")[1];
        if(!preToken.equalsIgnoreCase(preTokenRedis)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_STATUS_ERROR);
        }

        //preToken验证成功
        //去数据库根据id查询数据
        Users users = usersService.getById(userId);

        if(users==null){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }

        //用户信息存入redis中
        //跨界面时，获取不到userID，所以暂存在redis 后面界面跳转需要用
        redis.set(REDIS_SAAS_USER_INFO+":temp:"+preToken.substring(0,6),new Gson().toJson(users));
        return GraceJSONResult.ok();

    }

    // ====================跳过扫码功能 END============================

    /**
     * 定时查询QRToken是否被读取
     * @param qrToken
     * @return
     */
    @RequestMapping(method = RequestMethod.POST,path = "codeHasBeenRead1")
    public GraceJSONResult getQRToken(String qrToken){

        String readStr = redis.get(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + qrToken);

        List<String> list = new ArrayList<>();

        if(StringUtils.isBlank(readStr)){
            return GraceJSONResult.ok(list);
        }

        // 0,qrToken 1,preToken
        String[] strs = readStr.split(",");

        if(strs.length < 2){
            list.add(strs[0]);
        }else{
            list.add(strs[0]);
            list.add(strs[1]);
        }

        //若0，未标记 若1，已标记，等待前端点确认登陆
        //返回前端让前端携带token
        return GraceJSONResult.ok(list);

    }

    @RequestMapping(method = RequestMethod.POST,path = "goQRLogin1")
    public GraceJSONResult goQRLogin(String userId,String qrToken,String preToken){

        String preTokenRedisArr = redis.get(SAAS_PLATFORM_LOGIN_TOKEN_READ + ":" + qrToken);

        if(StringUtils.isBlank(preTokenRedisArr)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_STATUS_ERROR);
        }

        String preTokenRedis = preTokenRedisArr.split(",")[1];
        if(!preToken.equalsIgnoreCase(preTokenRedis)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_STATUS_ERROR);
        }

        //preToken验证成功
        //去数据库根据id查询数据
        Users users = usersService.getById(userId);

        if(users==null){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }

        //用户信息存入redis中
        //跨界面时，获取不到userID，所以暂存在redis 后面界面跳转需要用
        String json = new Gson().toJson(users);
        log.info("拿到的数据：{}",json);
        redis.set(REDIS_SAAS_USER_INFO+":temp:"+preToken.substring(0,6),json);
        return GraceJSONResult.ok();

    }

    /**
     * 校验通过后，界面自刷新，即preToken通过上面的键获取到了users对象的json
     * 根据json加载界面
     * @param preToken
     * @return
     */
    @RequestMapping(method = RequestMethod.POST,path = "checkLogin")
    public GraceJSONResult checkLogin(String preToken){

        if(StringUtils.isBlank(preToken)){
            return GraceJSONResult.ok("");
        }

        //用户临时信息
        String userJson = redis.get(REDIS_SAAS_USER_INFO + ":temp:" + preToken.substring(0,6));

        if(StringUtils.isBlank(userJson)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }

        //生成saas端长期有效的token
        String saasJwtToken = jwtUtils.createJwtWithPrefix(userJson,TOKEN_SAAS_PREFIX);

        //存入用户信息，长期有效
        redis.set(REDIS_SAAS_USER_INFO+":"+saasJwtToken,userJson);

        return GraceJSONResult.ok(saasJwtToken);
    }

    @RequestMapping(method = RequestMethod.GET,path = "info")
    public GraceJSONResult info(String token){

        if(StringUtils.isBlank(token)){
            return GraceJSONResult.ok("");
        }

        String userJson = redis.get(REDIS_SAAS_USER_INFO + ":" + token);

        Users users = new Gson().fromJson(userJson, Users.class);
        SaasUserVO saasUserVO = new SaasUserVO();
        BeanUtils.copyProperties(users,saasUserVO);
        return GraceJSONResult.ok(saasUserVO);

    }

    @RequestMapping(method = RequestMethod.POST,path = "logout")
    public GraceJSONResult logout(String token){

        redis.del(REDIS_SAAS_USER_INFO + ":" + token);
        return GraceJSONResult.ok();
    }
}
